package org.example.rabbitmq.config;

import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.example.core.utils.R;
import org.example.rabbitmq.api.MqLogService;
import org.example.rabbitmq.api.domain.MqMessage;
import org.example.rabbitmq.constant.RabbitMQConstants;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;

/**
 * @author 小杰_cc
 * @version 1.0
 */
@Slf4j
@Configuration
public class MqConfirmConfig implements ApplicationContextAware {

    @Autowired
    private MqLogService mqLogService;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // 到了交换机未到达队列
        RabbitTemplate rabbitTemplate = applicationContext.getBean(RabbitTemplate.class);
        rabbitTemplate.setReturnsCallback(returnedMessage -> {
            // 获取到发送的消息
            Message message = returnedMessage.getMessage();
            // 获取重试次数
            Integer retryCount = (Integer) message.getMessageProperties().getHeaders().getOrDefault(RabbitMQConstants.RETRY_COUNT, 0);
            if (retryCount < RabbitMQConstants.MAX_RETRY_COUNT){
                retryCount++;
                message.getMessageProperties().getHeaders().put(RabbitMQConstants.RETRY_COUNT, retryCount);
                // 重新发送消息
                rabbitTemplate.send(returnedMessage.getExchange(),returnedMessage.getRoutingKey(), message);
            }else {
                // 到达最大重试次数，记录日志(写入数据库)
                R<?> result = mqLogService.add(new MqMessage(message.getMessageProperties().getMessageId(), JSON.toJSONString(message)
                        , returnedMessage.getExchange(), returnedMessage.getRoutingKey(), 0));

                if (result.getCode() != 0){
                    // 失败的消息远程保存失败了，发信息通知管理员了
                    log.error("消息发送和记录失败，消息id为:{}", message.getMessageProperties().getMessageId());
                }
                log.error("消息发送失败，记录成功，消息id为:{}", message.getMessageProperties().getMessageId());
            }
        });
    }
}